import torch
from torch import nn
"""1. 创建卷积核对象"""
# 输入图像的通道数=1(灰度图像),卷积核的种类数=3
# 卷积核的shape是3*3的,扫描步长为1,不加padding
layer = nn.Conv2d(1,3,kernel_size=3,stride=1,padding=0)
"""2. 输入的原始图像"""
# 样本数=1,通道数=1,图像的shape是28*28的
x = torch.rand(1,1,28,28)

"""3. 使用上面定义的卷积层layer和输入x,完成一次卷积的前向运算"""
out = layer.forward(x)
# 得到的还是1张图片,因为用了3种kernel所以输出的通道数变成3了
# 因为没加padding,原来28*28的图像在3*3卷积下得到边长是28-3+1=26

print(out.shape)
# 输出形状： torch.Size([1,3,26,26])

"""4. 添加padding实验"""
# 使用padding为1,所以原始图像上下左右都加了一层0
layer = nn.Conv2d(1, 3, kernel_size=3, stride=1, padding=1)
print(layer.forward(x).shape)  
# 输出形状： torch.Size([1, 3, 28, 28])

"""5. 步长设置为2实验"""
# stride设置为2,也就是每次移动2格子(向上或者向右)
layer = nn.Conv2d(1, 3, kernel_size=3, stride=2, padding=1)
# 相当于每次跳1像素地扫描,输出的Feature Map直接小了一半

print(layer.forward(x).shape)  
# 输出形状： torch.Size([1, 3, 14, 14])

"""6. 实际使用,直接使用对象调用,不需要调用forward()"""
out = layer(x)
print(out.shape)  
# 输出形状：torch.Size([1, 3, 14, 14]) 
